﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net.Mail;
using System.IO;
using System.Net.Mime;

namespace TaskLogger
{
    public partial class Console : Form
    {
        public Console()
        {
            InitializeComponent();
            comboBoxProject.Validated += new EventHandler(comboBoxProject_Validated);
            comboBoxTask.Validated += new EventHandler(comboBoxTask_Validated);
            comboBoxCategory.Validated += new EventHandler(comboBoxCategory_Validated);
            comboBoxAssigner.Validated += new EventHandler(comboBoxAssigner_Validated);
            Properties.Settings.Default.Reload();
        }

        void comboBoxAssigner_Validated(object sender, EventArgs e)
        {
            assignerValid = true;
            UpdateDisplay();
        }

        void comboBoxCategory_Validated(object sender, EventArgs e)
        {
            categoryValid = true;
            UpdateDisplay();
        }

        void comboBoxTask_Validated(object sender, EventArgs e)
        {
            taskValid = true;
            UpdateDisplay();
        }

        void comboBoxProject_Validated(object sender, EventArgs e)
        {
            projectValid = true;
            UpdateDisplay();
        }
        
        public void RefreshComboLists()
        {
            int projectId = -1;
            int assignerId = -1;
            int categoryId = -1;
            if (selectedTask >= 0)
            {
                projectId = (int)DataManager.TimeTrackerData.Task[selectedTask].ProjectRow["Id"];
                assignerId = (int)DataManager.TimeTrackerData.Task[selectedTask].AssignerRow["Id"];
                categoryId = (int)DataManager.TimeTrackerData.Task[selectedTask].CategoryRow["Id"];
            }
            comboBoxProject.Items.Clear();
            foreach (DataRow row in DataManager.TimeTrackerData.Project.Rows)
            {
                var index = comboBoxProject.Items.Add(new ListItem(row["Name"].ToString(), (int)row["Id"]));
                if ((int)row["Id"] == projectId)
                    comboBoxProject.SelectedIndex = index;
            }
            comboBoxTask.Items.Clear();
            foreach (DataRow row in DataManager.TimeTrackerData.Task.Rows)
            {
                var index = comboBoxTask.Items.Add(new ListItem(row["Name"].ToString(), (int)row["Id"]));
                if ((int)row["Id"] == selectedTask)
                    comboBoxTask.SelectedIndex = index;
            }
            comboBoxAssigner.Items.Clear();
            foreach (DataRow row in DataManager.TimeTrackerData.Assigner.Rows)
            {
                var index = comboBoxAssigner.Items.Add(new ListItem(row["Name"].ToString(), (int)row["Id"]));
                if ((int)row["Id"] == assignerId)
                    comboBoxAssigner.SelectedIndex = index;
            }
            comboBoxCategory.Items.Clear();
            foreach (DataRow row in DataManager.TimeTrackerData.Category.Rows)
            {
                var index = comboBoxCategory.Items.Add(new ListItem(row["Name"].ToString(), (int)row["Id"]));
                if ((int)row["Id"] == categoryId)
                    comboBoxCategory.SelectedIndex = index;
            }
        }

        private int selectedTask = -1;

        public void CommitTaskSelection()
        {
            int projectId;
            int categoryId;
            int assignerId;
            if (comboBoxProject.SelectedItem == null)
            {
                TimeTrackerData.ProjectRow row = DataManager.TimeTrackerData.Project.NewProjectRow();
                row.Name = comboBoxProject.Text;
                int index = comboBoxProject.Items.IndexOf(row.Name);
                if (index >= 0)
                {
                    ListItem item = (ListItem)comboBoxProject.Items[index];
                    projectId = item.Id;
                }
                else
                {
                    DataManager.TimeTrackerData.Project.Rows.Add(row);
                    projectId = row.Id;
                }
            }
            else
            {
                projectId = ((ListItem)comboBoxProject.SelectedItem).Id;
            }
            if (comboBoxCategory.SelectedItem == null)
            {
                if (comboBoxCategory.Text == "")
                {
                    categoryId = -1;
                }
                else
                {
                    TimeTrackerData.CategoryRow row = DataManager.TimeTrackerData.Category.NewCategoryRow();
                    row.Name = comboBoxCategory.Text;
                    int index = comboBoxCategory.Items.IndexOf(row.Name);
                    if (index >= 0)
                    {
                        ListItem item = (ListItem)comboBoxCategory.Items[index];
                        categoryId = item.Id;
                    }
                    else
                    {
                        DataManager.TimeTrackerData.Category.Rows.Add(row);
                        categoryId = row.Id;
                    }
                }
            }
            else
            {
                categoryId = ((ListItem)comboBoxCategory.SelectedItem).Id;
            }
            if (comboBoxAssigner.SelectedItem == null)
            {
                TimeTrackerData.AssignerRow row = DataManager.TimeTrackerData.Assigner.NewAssignerRow();
                row.Name = comboBoxAssigner.Text;
                int index = comboBoxAssigner.Items.IndexOf(row.Name);
                if (index >= 0)
                {
                    ListItem item = (ListItem)comboBoxAssigner.Items[index];
                    assignerId = item.Id;
                }
                else
                {
                    DataManager.TimeTrackerData.Assigner.Rows.Add(row);
                    assignerId = row.Id;
                }
            }
            else
            {
                assignerId = ((ListItem)comboBoxAssigner.SelectedItem).Id;
            }
            if (comboBoxTask.SelectedItem == null)
            {
                TimeTrackerData.TaskRow row = DataManager.TimeTrackerData.Task.NewTaskRow();
                row.Name = comboBoxTask.Text;
                int index = comboBoxTask.Items.IndexOf(row.Name);
                if (index >= 0)
                {
                    ListItem item = (ListItem)comboBoxTask.Items[index];
                    selectedTask = item.Id;
                }
                else
                {
                    row.AssignedBy = assignerId;
                    row.Project = projectId;
                    if (categoryId >= 0)
                        row.Category = categoryId;
                    else
                        row.SetCategoryNull();
                    DataManager.TimeTrackerData.Task.Rows.Add(row);
                    selectedTask = row.Id;
                }
            }
            else
            {
                selectedTask = ((ListItem)comboBoxTask.SelectedItem).Id;
            } 
            DataManager.SaveData();
        }

        private bool busyTiming = false;
        public bool BusyTiming
        {
            get { return busyTiming; }
        }

        public string SelectedTask
        {
            get
            {
                if (selectedTask == -1)
                    return null;
                return ((TimeTrackerData.TaskRow) DataManager.TimeTrackerData.Task.Rows.Find(selectedTask)).Name;
            }

        }

        private void buttonStartStop_Click(object sender, EventArgs e)
        {
            if (!busyTiming)
            {
                if (TaskSelectionIsValid)
                {
                    CommitTaskSelection();
                    RefreshComboLists();
                    StartTiming();
                    Hide();
                }
            }
            else
            {
                StopTiming();
            }
        }

        Stopwatch stopWatch;

        public void StopTiming()
        {
            if (!busyTiming)
                return;
            if (stopWatch == null)
                throw new ApplicationException("Busy timing but Stopwatch is null!");
            stopWatch.Stop();
            busyTiming = false;
            UpdateDisplay();
            if (TimingStopped != null)
                TimingStopped(stopWatch, new EventArgs());
            if (selectedTask >= 0)
            {
                TimeTrackerData.TimeRow row = DataManager.TimeTrackerData.Time.NewTimeRow();
                row.Task = selectedTask;
                row.Seconds = (long)stopWatch.Elapsed.TotalSeconds;
                row.Start = DateTime.Now.Subtract(TimeSpan.FromSeconds(row.Seconds));
                row.End = DateTime.Now;
                DataManager.TimeTrackerData.Time.Rows.Add(row);
                DataManager.SaveData();
            }
            else
            {
                throw new ApplicationException("Stopwatch was stopped, but no task has been selected!");
            }
        }

        public void StartTiming()
        {
            if (busyTiming)
                return;
            stopWatch = Stopwatch.StartNew();
            busyTiming = true;
            UpdateDisplay();
            if (TimingStarted != null)
                TimingStarted(stopWatch, new EventArgs());
        }

        private void comboBox_Validating(object sender, CancelEventArgs e)
        {
            StopTiming();
            ComboBox combo = (ComboBox)sender;
            if (combo.Text == "")
            {
                e.Cancel = true;
                errorProvider.SetError(combo, "Can not be empty!");
                DisableStart();
            }
        }

        private bool startDisabled = true;
        private void DisableStart()
        {
            startDisabled = true;
            UpdateDisplay();
        }

        public event EventHandler TimingStopped;
        public event EventHandler TimingStarted;

        private void EnableStart()
        {
            startDisabled = false;
            UpdateDisplay();
        }

        private void comboBoxProject_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private bool projectValid = false;
        private bool categoryValid = false;
        private bool taskValid = false;
        private bool assignerValid = false;

        private void comboBox_Validated(object sender, EventArgs e)
        {
            ComboBox combo = (ComboBox)sender;
            errorProvider.SetError(combo, "");
        }

        private void Console_Load(object sender, EventArgs e)
        {
            RefreshComboLists();
            UpdateDisplay();
        }

        private bool TaskSelectionIsValid
        {
            get { return (projectValid && taskValid && assignerValid); }
        }

        private void UpdateDisplay()
        {
            startDisabled = !TaskSelectionIsValid;
            if (!busyTiming)
            {
                if (startDisabled)
                {
                    buttonStartStop.Enabled = false;
                    errorProvider.SetError(buttonStartStop, "");
                }
                else
                {
                    buttonStartStop.Enabled = true;
                    errorProvider.SetError(buttonStartStop, "Remember to start timing!");
                }
                buttonStartStop.Text = "Start Timing";
            }
            else
            {
                buttonStartStop.Text = "Stop Timing";
                errorProvider.SetError(buttonStartStop, "");
            }

        }

        

        private void Console_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                if (!busyTiming)
                {
                    if (MessageBox.Show("Close without tracking your time?", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.OK)
                        Hide();
                }
                else
                {
                    Hide();
                }
            }
        }

        private void comboBoxCategory_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void buttonReports_Click(object sender, EventArgs e)
        {
            ReportingForm rf = new ReportingForm();
            rf.ShowDialog();
        }

        private void textbox_Validated(object sender, EventArgs e)
        {
            Properties.Settings.Default.Save();
        }

        private bool reportSentThisWeek;

        private void timerLong_Tick(object sender, EventArgs e)
        {
            if (DateTime.Now.DayOfWeek == DayOfWeek.Friday && DateTime.Now.TimeOfDay > TimeSpan.Parse(Properties.Settings.Default.DayEnd))
            {
                try
                {
                    MailMessage email = new MailMessage("tasklogger@nowhere.com", Properties.Settings.Default.EmailAddresses, "TaskLogger Report", "Please find the weekly report from " + Environment.UserName + " attached.");
                    string report = ReportingForm.GenerateReport(DateTime.Now.AddDays(-5).Date, DateTime.Now.AddDays(1).Date).ToString();
                    string reportFilename = Path.GetTempPath() + "\\" + Environment.UserName + "_" + DateTime.Now.ToShortDateString().Replace('/','-') + ".csv";
                    File.WriteAllText(reportFilename, report);
                    email.Attachments.Add(new Attachment(reportFilename, MediaTypeNames.Text.Plain));
                    SmtpClient smtp = new SmtpClient(Properties.Settings.Default.SMTPServer);
                    smtp.Send(email);
                    reportSentThisWeek = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Failed to send weekly report! {0}", ex.Message), "TaskLogger", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
            }
            else
            {
                reportSentThisWeek = false;
            }
        }

    }
}
